package fybug.nulll.pdstream.IO;
import com.sun.istack.internal.NotNull;
import com.sun.istack.internal.Nullable;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
/**
 * <h2>NI/O 方法封装.</h2>
 *
 * @author fybug
 * @version 0.0.3
 * @see java.nio
 * @since JDK 1.5
 */
@SuppressWarnings( "all" )
public final
class NI_O {
    /** {@Hide} */
    @Deprecated
    private
    NI_O() {}

    /**
     * <p>使用文件通道进行零复制.</p>
     * <pre>
     * 生成文件读写流后使用 {@link #zerCopy(FileChannel, FileChannel)} 进行复制
     * 复制速度比其他方法快很多
     * 复制完成后会关闭文件读写流
     * </pre>
     *
     * @param in  从该文件获取
     * @param out 复制到该文件
     *
     * @see #zerCopy(FileChannel, FileChannel)
     */
    public static
    void zerCopy(@NotNull final File in, @NotNull final File out) throws IOException
    {
        @NotNull FileInputStream inputStream = null;
        @NotNull FileOutputStream outputStream = null;
        try {
            inputStream = new FileInputStream(in);
            outputStream = new FileOutputStream(out);
            zerCopy(inputStream.getChannel(), outputStream.getChannel());
        } finally {
            try {
                if (inputStream != null)
                    inputStream.close();
            } catch ( IOException ignored ) {
            }
            try {
                if (outputStream != null)
                    outputStream.close();
            } catch ( IOException ignored ) {
            }
        }
    }

    /**
     * <p>使用文件通道进行零复制.</p>
     * <pre>
     * 复制过程中会获取文件锁
     * 复制速度比其他方法快很多
     * 复制完成后会关闭文件通道
     * </pre>
     *
     * @param in  从该文件获取
     * @param out 复制到该文件
     */
    public static
    void zerCopy(@NotNull final FileChannel in, @NotNull final FileChannel out) throws IOException
    {
        //* 获取文件锁，保证通道稳定性 *//
        @Nullable FileLock outLock = null;
        try {
            // 获取通道锁
            do {
                outLock = out.tryLock();
            }
            while( outLock == null );
            if (!in.isOpen() || !outLock.isValid())
                return;
            /* 进行零复制 */
            long size; // 文件长度
            size = in.size();
            // 进行复制
            in.transferTo(0, size, out);
        } finally {
            try {
                in.close();
            } catch ( IOException ignored ) {
            }
            try {
                if (outLock != null)
                    outLock.close();
            } catch ( IOException ignored ) {
            }
            try {
                out.close();
            } catch ( IOException ignored ) {
            }
        }
    }
}
